package com.just521.xinshoutong.http;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.util.EntityUtils;
import org.xmlpull.v1.XmlPullParserException;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import com.just521.xinshoutong.R;
import com.just521.xinshoutong.common.CommonDefine;
import com.just521.xinshoutong.errorHandler.errorDefine;
import com.just521.xinshoutong.xml.CommonXmlMaker;
import com.just521.xinshoutong.xml.CommonXmlParser;
import com.mobclick.android.MobclickAgent;

class HttpThread extends Thread{
	private int timeoutConnection = 30000;  
	private int timeoutSocket = 30000; 
	private BasicHttpParams httpParameters;
	HttpHelperWraper http;
	List<HttpHelperWraper.HttpRequestParam> mreqparams=new ArrayList<HttpHelperWraper.HttpRequestParam>();
	byte[] mlock=new byte[0];
	public HttpThread(){
		httpParameters = new BasicHttpParams();
		httpParameters.setParameter("http.protocol.version", HttpVersion.HTTP_1_0);
		HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection); 

		HttpConnectionParams.setSoTimeout(httpParameters,timeoutSocket); 
		http = new HttpHelperWraper();
		start();
	}
	public void postRequest(HttpHelperWraper.HttpRequestParam param){
		synchronized (mlock) {
			if(param.task.equals("getMatchList") || param.task.equals("getMatchListDif")){
				
				for(HttpHelperWraper.HttpRequestParam item:mreqparams){
					if( item.task.equals(param.task) ){
						return;
					}
				}
			}
			
			mreqparams.add(param);
		}
		Message msg = new Message();
		msg.obj=param;
		if(mHandler==null){
			try{
				sleep(300);
			}catch(InterruptedException e){
				
			}
		}
		mHandler.sendMessage(msg);
	}
	public Handler mHandler=null;
	public void run() {
		Looper.prepare();
		
		mHandler = new Handler() {
			public void handleMessage(Message msg) {
				HttpClient clienttemp = new DefaultHttpClient(httpParameters);	
				HttpHelperWraper.HttpRequestParam param = (HttpHelperWraper.HttpRequestParam)msg.obj;
				do{
					boolean b =http.executeTask(param,clienttemp);
					if(b){
						synchronized (mlock) {
							mreqparams.remove(param);
						}
						break;
					}
					try{
						
						sleep(3000);
					}catch(Exception e){
						
					}
				}while(true);
				
				super.handleMessage(msg);  
			}
		};
		
		Looper.loop();
		
		
    }
}	

public class HttpHelperWraper{
	static  BasicHttpParams httpParameters;
	
	
	public static final String BOUNDARY = "7cd4a6d158c";
    public static final String MP_BOUNDARY = "--" + BOUNDARY;
    public static final String END_MP_BOUNDARY = "--" + BOUNDARY + "--";
    public static final String MULTIPART_FORM_DATA = "multipart/form-data";
    static private HttpThread mThread=new HttpThread();
	public static void init(Context ctx){
		
		int timeoutConnection = 30000;  
		int timeoutSocket = 30000; 
		if(httpParameters==null){
			
			httpParameters = new BasicHttpParams();
			httpParameters.setParameter("http.protocol.version", HttpVersion.HTTP_1_0);
		}
		HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection); 
		HttpConnectionParams.setSoTimeout(httpParameters,timeoutSocket); 
		
		
		// Create and initialize HTTP parameters  
//        HttpParams params = new BasicHttpParams();  
//        ConnManagerParams.setMaxTotalConnections(httpParameters, 100);  
//        HttpProtocolParams.setVersion(httpParameters, HttpVersion.HTTP_1_1);  
  
        // Create and initialize scheme registry  
//        SchemeRegistry schemeRegistry = new SchemeRegistry();  
//        schemeRegistry.register(  
//                new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));  
  
        // Create an HttpClient with the ThreadSafeClientConnManager.  
        // This connection manager must be used if more than one thread will  
        // be using the HttpClient.  
//        ClientConnectionManager cm = new ThreadSafeClientConnManager(httpParameters, schemeRegistry);  
//        httpclient = new DefaultHttpClient(cm, httpParameters);  
        
//		getHostUrl(ctx);
	}
	public interface OnNetListener{
		public void onNetSuccess(HttpRequestParam param);
		public void onNetError(HttpRequestParam param);
	}
	public class HttpRequestParam{
		public Context  ctx;
		public String url;
		public String task;
		public HashMap<String, Object> nodesrequest;
		public OnNetListener listener;
		public String rstmsg;
		public HashMap<String, Object> nodesresult;
		public long	ltimestamp;
		public Map<String,ByteArrayOutputStream> attatchfiles;
	}
	
	private DownloadListener mDownloadListener;
	public interface DownloadListener{
		public void onDownloadBegin(int total);
		public void onDownloadUpdateProgress(int cur);
		public void onDownloadEnd(String file);
	}
	
	public  InputStream   is = null;
//	static String hosturl;
//	public  String		  url = "http://mylucky.oicp.net/trunk/mobile/index.php";
	
	public  String		  url = "mobile/index.php";
	public String		  ret_from_net = null;
	final static String Pattern_Xml_Result = "retXml:(.+)";
	final static String Pattern_Normal_Result = "errMsg:(.+)";
	
	public static Pattern mpattern_xml = Pattern.compile(Pattern_Xml_Result,Pattern.DOTALL); 
	public static Pattern mpattern_err = Pattern.compile(Pattern_Normal_Result,Pattern.DOTALL); 
	
	 private static final int NET_CONNECT = 1;  
	 private static final int NET_COMPLETE = 2;  
	 private static final int NET_ERROR = 3;  
	 private static final int NET_UPDATE = 4;
	 
	 private static final int DOWN_BEGIN = 11;
	 private static final int DOWN_UPDATE_PROGRESS = 12;
	 private static final int DOWN_END = 13;
	 
	 EventHandler mHandler = new EventHandler();  
	 
	 public static String   HostUrl="";
//	 public  Context  ctx  = null;
	 
	 private String mRequestTask;
	 public String getRequestTask(){
		return mRequestTask;
	}
	 public HttpRequestParam getParam(){
		 return new HttpRequestParam();
	 }
	 public static String getHostUrl(Context ctx){
		 String url = "http://lover.just521.com/";
		 String temp = MobclickAgent.getConfigParams(ctx, CommonDefine.OnlineParam.Param_hosturl);
		 if(temp!=null && !temp.equals("")){
			 url = temp;
		 }
		 
		return url;
//	   return "http://192.168.1.166/mylover/trunkRloverweb/";
//	   return "http://lover.just521.com/";
	 }

	 public  void setUrl(String  url_str )
	 {
		 url = url_str;
	 }
	 
	
	public boolean checknetworkstatus()
	{
		return true;
	}
	public boolean SyncTask(HttpRequestParam param){
		HttpClient clienttemp = new DefaultHttpClient(httpParameters);	
		return executeTask(param,clienttemp);
	}
	public boolean SyncTaskSyncRst(HttpRequestParam param){
		HttpClient clienttemp = new DefaultHttpClient(httpParameters);	
		return executeTaskSyncRst(param,clienttemp);
	}
	public void AsyncTask(HttpRequestParam param){
		final HttpRequestParam paramt = param;
		new Thread(new Runnable() {  
            public void run() {  
            	HttpClient clienttemp = new DefaultHttpClient(httpParameters);	
            	executeTask(paramt,clienttemp);
            }  
        }).start(); 
	}
	public void LinearAsyncTask(HttpRequestParam param){
		mThread.postRequest(param);
	}
	public boolean executeTaskSyncRst(HttpRequestParam param,HttpClient client){
		return executeTaskInternal(param,client,true);
	}
	public boolean executeTask(HttpRequestParam param,HttpClient client){
		return executeTaskInternal(param,client,false);
	}
	public boolean executeTaskInternal(HttpRequestParam param,HttpClient client,boolean bissyncrst){
		short sRet  = errorDefine.HTTP_TIMEOUT_Error;
		Log.d("zhaodsh", "netaccess:"+param.task);
		boolean bRet=false;
		String temp_task = param.task;
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		params.add(new BasicNameValuePair("task", temp_task));
		String xml_buf = null;
		if(param.nodesrequest != null )
		{
			
			try{
	    		xml_buf = new CommonXmlMaker().makexml(param.nodesrequest);
	    	}catch(IOException e){
	    	}
			try {
					params.add(new BasicNameValuePair("xmlString", xml_buf));
			} catch (Exception e1) {
				e1.printStackTrace();
			}
					
		}
		String ret_from_net = null;
		do{
			HostUrl = getHostUrl(param.ctx);
			HttpPost httpRequest = new HttpPost(HostUrl+url);
			HttpEntity httpentity = null;
			
			HttpResponse httpResponse = null;
			try
			{ 
				if(param.attatchfiles!=null){
					byte[] data = null;
					ByteArrayOutputStream bos = new ByteArrayOutputStream(1024 * 50);
					
					normalParamsUpload(bos, params);
					httpRequest.setHeader("Content-Type", MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY);
					
					binaryParamsUpload(bos, param.attatchfiles);
					
					data = bos.toByteArray();
					bos.close();
					ByteArrayEntity formEntity = new ByteArrayEntity(data);
					httpRequest.setEntity(formEntity);
				}else{
					
					httpentity = new UrlEncodedFormEntity(params,"utf-8");
					httpRequest.setEntity(httpentity);
				}
				httpRequest.setHeader("Connection", "close");
				NetworkControl.NetType netType = NetworkControl.getNetType(param.ctx);
				if (netType != null && netType.isWap()) {
					HttpHost proxy = new HttpHost(netType.getProxy(), netType.getPort());
					client.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, proxy);
				}
				
				httpResponse = client.execute(httpRequest);
				int code = httpResponse.getStatusLine().getStatusCode(); 
				if ( code == HttpStatus.SC_OK)
				{ 
					String retBuf = EntityUtils.toString(httpResponse.getEntity(),"utf-8");	
					String result[]=retBuf.split(";");
					Matcher m = mpattern_err.matcher(result[0]);
					if(m.find()){
						String y = m.group(1);
						if(y.equals("ok")){
							bRet=true;
							if(result.length>1)
							{
								m = mpattern_xml.matcher(result[1]); 
						        if (m.find())
						        {
						        	ret_from_net = m.group(1);
						        }	
						        try {
									CommonXmlParser parser = new CommonXmlParser();
									if(ret_from_net != null){
										parser.parse(ret_from_net);
										param.nodesresult = parser.getParseResult();
									}else{
										param.nodesresult = null;
									}
									
									
								} catch (XmlPullParserException e) {
									e.printStackTrace();
								} catch (IOException e) {
									e.printStackTrace();
								}
								if(bissyncrst){
									param.listener.onNetSuccess(param);
								}else{
									
									sendMessage(NET_COMPLETE, param);  
								}
							}
							else
							{
								if(bissyncrst){
									param.listener.onNetSuccess(param);
								}else{
									
									sendMessage(NET_COMPLETE, param);  
								}
//								sendMessage(NET_COMPLETE, param);  
							}
							
						}
						else
						{
							param.rstmsg=y;
							if(bissyncrst){
								param.listener.onNetError(param);
							}else{
								
								sendMessage(NET_ERROR, param);  
							}
//							sendMessage(NET_ERROR, param);  
						}
						
					}else
					{
						param.rstmsg=retBuf;
						if(bissyncrst){
							param.listener.onNetError(param);
						}else{
							
							sendMessage(NET_ERROR, param);  
						}
//						sendMessage(NET_ERROR,param);  
					}
					
				}
				else
				{
					param.rstmsg=CommonDefine.getResources(param.ctx).getString(R.string.neterr_message);
					if(bissyncrst){
						param.listener.onNetError(param);
					}else{
						
						sendMessage(NET_ERROR, param);  
					}
//					sendMessage(NET_ERROR, param);  
				}
			}
			catch (ClientProtocolException e)
			{
				param.rstmsg=CommonDefine.getResources(param.ctx).getString(R.string.neterr_message);
				if(bissyncrst){
					param.listener.onNetError(param);
				}else{
					
					sendMessage(NET_ERROR, param);  
				}
//				sendMessage(NET_ERROR, param); 
			}
			catch (IOException e)
			{
				param.rstmsg=CommonDefine.getResources(param.ctx).getString(R.string.neterr_message);
				if(bissyncrst){
					param.listener.onNetError(param);
				}else{
					
					sendMessage(NET_ERROR, param);  
				}
//				sendMessage(NET_ERROR, param); 
			}


			httpRequest = null;
			httpentity = null;
			httpResponse = null;
		}while(false);
		return bRet;
		
	}
	
	private void normalParamsUpload(ByteArrayOutputStream bos,List<NameValuePair> params){
		String key = "";
        for (int loc = 0; loc < params.size(); loc++) {
            key = params.get(loc).getName();
            StringBuilder temp = new StringBuilder(10);
            temp.setLength(0);
            temp.append(MP_BOUNDARY).append("\r\n");
            temp.append("content-disposition: form-data; name=\"").append(key).append("\"\r\n\r\n");
            temp.append(params.get(loc).getValue()).append("\r\n");
            byte[] res = temp.toString().getBytes();
            try {
            	bos.write(res);
            } catch (IOException e) {
//                throw new WeiboException(e);
            }
        }
		
	}
	private void binaryParamsUpload(ByteArrayOutputStream bos,Map<String,ByteArrayOutputStream> attatchfiles){
		
		Iterator it=attatchfiles.entrySet().iterator();
		while(it.hasNext()){
			Map.Entry entry=(Map.Entry)it.next();
			String key=(String)entry.getKey();
			ByteArrayOutputStream bin=(ByteArrayOutputStream)entry.getValue();
			StringBuilder temp = new StringBuilder();

	        temp.append(MP_BOUNDARY).append("\r\n");
	        temp.append("Content-Disposition: form-data; name=\""+key+"\";")
	                .append("\"\r\n");
	        String filetype = "application/octet-stream";
	        temp.append("Content-Type: ").append(filetype).append("\r\n\r\n");
	        byte[] res = temp.toString().getBytes();
	        try {
	        	bos.write(res);
	        	bos.write(bin.toByteArray());
//	            imgpath.compress(CompressFormat.PNG, 75, out);
	        	bos.write("\r\n".getBytes());
	        	bos.write(("\r\n" + END_MP_BOUNDARY).getBytes());
	        } catch (IOException e) {
//	            throw new WeiboException(e);
	        } finally {
	            
	        }
		}
		
		
	}
	public void downloadFile(String url,DownloadListener DownloadListener,String filename ){
		mDownloadListener = DownloadListener;
		final String urltemp = url;
		final String filenametemp = filename;
		new Thread(new Runnable() {  
            public void run() {  
            		
            	try {
					down_file(urltemp,"/sdcard/downloads/lucky/",filenametemp);
					//涓嬭浇鏂囦欢锛屽弬鏁帮細绗竴涓猆RL锛岀浜屼釜瀛樻斁璺緞
				} catch (ClientProtocolException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
            }  
        }).start();  
	}
	private void sendMessage(int what, Object obj) {  
        Message msg = mHandler.obtainMessage(what, obj);  
        mHandler.sendMessage(msg);  
    }  
  
	private void sendMessage(int what) {  
        Message msg = mHandler.obtainMessage(what);  
        mHandler.sendMessage(msg);  
    }  
  
	private void sendMessage(int what, int arg1, int arg2) {  
        Message msg = mHandler.obtainMessage(what, arg1, arg2);  
        mHandler.sendMessage(msg);  
    }  	
	private void sendMessage(int what, int arg1) {  
        Message msg = new Message();
        msg.arg1 = arg1;
        msg.what =what;
        mHandler.sendMessage(msg);  
    }  
	
	
	    private class EventHandler extends Handler {  
	        private HttpHelperWraper mManager;  
	  
	        public EventHandler() {  
	        }  
	  
	        // 澶勭悊鎺ユ敹鍒扮殑娑堟伅  
	        @Override  
	        public void handleMessage(Message msg) {  
	        	HttpRequestParam temp = (HttpRequestParam)msg.obj;
	        	if(temp.listener==null){
	        		return;
	        	}
	            switch (msg.what) {  
	           
	            case NET_COMPLETE:  
	            	temp.listener.onNetSuccess(temp);  
	                break;  
	            case NET_ERROR:  
	            	temp.listener.onNetError(temp);   
	                break; 
	            case DOWN_BEGIN:  
	                if (mDownloadListener != null)  
	                	mDownloadListener.onDownloadBegin(msg.arg1);  
	                break; 
	            case DOWN_UPDATE_PROGRESS:  
	                if (mDownloadListener != null)  
	                	mDownloadListener.onDownloadUpdateProgress(msg.arg1);  
	                break; 
	            case DOWN_END:  
	                if (mDownloadListener != null)  
	                	mDownloadListener.onDownloadEnd((String)msg.obj);  
	                break; 
	            default:  
	                break;  
	            }  
	        }  
	    }  
	  

	
    public static class NetworkControl {

    	/**
    	 * 鍒ゆ柇褰撳墠缃戠粶鐘舵�鏄惁鍙敤
    	 * @param context
    	 * @return
    	 */
    	public boolean getNetworkState(Context context){
    		ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    		NetworkInfo info = connectivityManager.getActiveNetworkInfo(); 

    		if(info != null)
    		{
    			return true;
    		}

    		return false;
    	}

    	/**
    	 * 鍒ゆ柇缃戠粶绫诲�
    	 * @param context
    	 * @return
    	 */
    	public static NetType getNetType(Context context){
    		ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    		if(connectivityManager == null) return null; 

    		NetworkInfo info = connectivityManager.getActiveNetworkInfo();
    		if(info == null) return null;

    		String type = info.getTypeName();

    		if (type.equalsIgnoreCase("WIFI")) {
    			// WIFI鏂瑰�
    			return null;
    		} else if(type.equalsIgnoreCase("MOBILE")) {
    			// GPRS鏂瑰�
    			String proxyHost = android.net.Proxy.getDefaultHost();
    	        if (proxyHost != null && !proxyHost.equals("")) {
    	        	// WAP鏂瑰�
    	        	NetType netType = new NetType();
    	            netType.setProxy(proxyHost);
    	        	netType.setPort(android.net.Proxy.getDefaultPort());
    	        	netType.setWap(true);
    	        	return netType;
    	        }
    		}
    		return null;
    	}

    	public static  class NetType {
    		private String apn = "";
    		private String proxy = "";
    		private String typeName = "";
    		private int port = 0;
    		private boolean isWap = false;

    		public String getApn() {
    			return apn;
    		}
    		public void setApn(String apn) {
    			this.apn = apn;
    		}
    		public int getPort() {
    			return port;
    		}
    		public void setPort(int port) {
    			this.port = port;
    		}
    		public String getProxy() {
    			return proxy;
    		}
    		public void setProxy(String proxy) {
    			this.proxy = proxy;
    		}
    		public boolean isWap() {
    			return isWap;
    		}
    		public void setWap(boolean isWap) {
    			this.isWap = isWap;
    		}
    		public String getTypeName() {
    			return typeName;
    		}
    		public void setTypeName(String typeName) {
    			this.typeName = typeName;
    		}
    	}

    }    
    public void down_file(String url,String path,String filenameOuter) throws IOException{
    	//涓嬭浇鍑芥暟   	
    	File f = new File(path);
    	f.mkdirs();
    	String filename=null;
    	if(filenameOuter==null){
    		
    		filename=url.substring(url.lastIndexOf("=") + 1);
    	}else{
    		filename=filenameOuter;
    	}
    	//鑾峰彇鏂囦欢鍚�
    	URL myURL = new URL(url);
    	HttpURLConnection conn = (HttpURLConnection) myURL.openConnection();
//    	conn.connect();
    	InputStream is = conn.getInputStream();
	    int fileSize = conn.getContentLength();//鏍规嵁鍝嶅簲鑾峰彇鏂囦欢澶у皬
	    if (fileSize <= 0) throw new RuntimeException("file size excepting");
	    if (is == null) throw new RuntimeException("stream is null");
	    String SDFilePath =  path+filename;
	    
//	    f.createNewFile();
	    FileOutputStream fos = new FileOutputStream(new File(SDFilePath));
	    //鎶婃暟鎹瓨鍏ヨ矾寰�鏂囦欢鍚�
	    byte buf[] = new byte[128];
	    int downLoadFileSize = 0;
	    sendMessage(DOWN_BEGIN,fileSize);
	    do
	      {
	    	//寰幆璇诲彇
	        int numread = is.read(buf);
	        if (numread == -1)
	        {
	          break;
	        }
	        fos.write(buf, 0, numread);
	        downLoadFileSize += numread;
 
	        sendMessage(DOWN_UPDATE_PROGRESS,downLoadFileSize);//鏇存柊杩涘害鏉�
	      } while (true);
	    
	    try
	      {
	        is.close();
	        fos.close();
	        sendMessage(DOWN_END,SDFilePath);//閫氱煡涓嬭浇瀹屾�
	      } catch (Exception ex)
	      {
	        Log.e("tag", "error: " + ex.getMessage(), ex);
	      }
	      conn.disconnect();
    }
	
	
	
}


